﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SStuff.FlowControls;
using System.Linq;
using System.Collections.Generic;

namespace SlflowTests
{
    [TestClass]
    public class Tests : SilverlightTest
    {


        private bool TestShortcutFirstToLast(FlowItemsControlBase flowControl, bool cyclic)
        {
            bool loaded = false;
            flowControl.ItemsSource = new string[] { "1", "2", "3", "4" };
            flowControl.SelectedIndex = 0;
            RoutedEventHandler onLoaded = null;
            onLoaded = (s, a) => { loaded = true; flowControl.Loaded -= onLoaded; };
            flowControl.Loaded+=onLoaded;
            TestPanel.Children.Add(flowControl);
            EnqueueConditional(() => loaded);
            EnqueueCallback(() => flowControl.SelectedIndex = 3);
            EnqueueDelay(100);
            EnqueueCallback(() => {
                bool tookShortcut = flowControl.LayoutOffset < 0 || flowControl.LayoutOffset > 3;
                if (cyclic)
                {
                    Assert.IsTrue(tookShortcut);
                }
                else
                {
                    Assert.IsFalse(tookShortcut);
                }
            });
            EnqueueTestComplete();
            return loaded;
        }

        private void TestShortcutCyclicLastToFirst(FlowItemsControlBase flowControl, bool cyclic)
        {
            bool loaded = false;
            flowControl.ItemsSource = new string[] { "1", "2", "3", "4" };
            flowControl.SelectedIndex = 3;

            RoutedEventHandler onLoaded = null;
            onLoaded = (s, a) => { loaded = true; flowControl.Loaded -= onLoaded; };
            flowControl.Loaded += onLoaded;
            TestPanel.Children.Add(flowControl);
            EnqueueConditional(() => loaded && flowControl.LayoutOffset == 3);
            EnqueueCallback(() => flowControl.SelectedIndex = 0);
            EnqueueDelay(100);
            EnqueueCallback(() => {
                bool tookShortcut = flowControl.LayoutOffset < 0 || flowControl.LayoutOffset > 3;
                if (cyclic)
                {
                    Assert.IsTrue(tookShortcut);
                }
                else
                {
                    Assert.IsFalse(tookShortcut);
                }
            });
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestShortcutCyclicFirstToLast2D()
        {
            var flowControl = new FlowItemsControl2D();
            TestShortcutFirstToLast(flowControl,true);
        }

        

        [TestMethod]
        [Asynchronous]
        public void TestShortcutCyclicLastToFirst2D()
        {
            var flowControl = new FlowItemsControl2D();
            TestShortcutCyclicLastToFirst(flowControl, true);
        }



        [TestMethod]
        [Asynchronous]
        public void TestShortcutCyclicFirstToLast3D()
        {
            var flowControl = new FlowItemsControl3D();
            TestShortcutFirstToLast(flowControl, true);
        }



        [TestMethod]
        [Asynchronous]
        public void TestShortcutCyclicLastToFirst3D()
        {
            var flowControl = new FlowItemsControl3D();
            TestShortcutCyclicLastToFirst(flowControl, true);
        }


        [TestMethod]
        [Asynchronous]
        public void TestShortcutNotCyclicFirstToLast2D()
        {
            var flowControl = new FlowItemsControl2D();
            flowControl.CyclicMode = false;
            TestShortcutFirstToLast(flowControl, false);
        }



        [TestMethod]
        [Asynchronous]
        public void TestShortcutNotCyclicLastToFirst2D()
        {
            var flowControl = new FlowItemsControl2D();
            flowControl.CyclicMode = false;
            TestShortcutCyclicLastToFirst(flowControl, false);
        }



        [TestMethod]
        [Asynchronous]
        public void TestShortcutNotCyclicFirstToLast3D()
        {
            var flowControl = new FlowItemsControl3D();
            flowControl.CyclicMode = false;
            TestShortcutFirstToLast(flowControl, false);
        }



        [TestMethod]
        [Asynchronous]
        public void TestShortcutNotCyclicLastToFirst3D()
        {
            var flowControl = new FlowItemsControl3D();
            flowControl.CyclicMode = false;
            TestShortcutCyclicLastToFirst(flowControl, false);
        }

        [TestMethod]
        public void TestCoverFlow2DGesture()
        {
            var testee = new CoverFlow2D();
            testee.SetAvailableSize(new Size(500, 500));
            double actual = testee.GetNormalizedOffsetAtPoint(new Point(0, 0));
            Assert.AreEqual(-1.0, actual);

            actual = testee.GetNormalizedOffsetAtPoint(new Point(500, 0));
            Assert.AreEqual(1.0, actual);


            actual = testee.GetNormalizedOffsetAtPoint(new Point(250, 0));
            Assert.AreEqual(0.0, actual);
        }


        [TestMethod]
        [Asynchronous]
        public void TestCyclic20Items()
        {
            Button yesBtn = new Button { Content = "Yes" };
            Button noBtn = new Button { Content = "No" };

            bool isOk = false;
            bool hasFinished = false;
            yesBtn.Click += delegate
            {
                isOk = true;
                hasFinished = true;
            };


            noBtn.Click += delegate
            {
                hasFinished = true;
            };

            var itemSource = new List<string>();
            for (int i = 0; i < 20; i++)
            {
                itemSource.Add("Item " + i);
            }

            var flowItems = new FlowItemsControl3D();
            flowItems.SelectedIndex = 0;

            flowItems.ItemsSource = itemSource;

            TestPanel.Children.Add(flowItems);
            TestPanel.Children.Add(new StackPanel
            {
                VerticalAlignment = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Center,
                Children = { new TextBlock { Text = "Is this no cyclic mode coverflow right ?" }, yesBtn, noBtn }
            });
            EnqueueConditional(() => hasFinished);
            EnqueueCallback(() => Assert.IsTrue(isOk));
            EnqueueTestComplete();
        }
        [TestMethod]
        [Asynchronous]
        public void TestCyclic11Items()
        {
            Button yesBtn = new Button { Content = "Yes" };
            Button noBtn = new Button { Content = "No" };

            bool isOk = false;
            bool hasFinished = false;
            yesBtn.Click += delegate
            {
                isOk = true;
                hasFinished = true;
            };


            noBtn.Click += delegate
            {
                hasFinished = true;
            };

            var itemSource = new List<string>();
            for (int i = 0; i < 11; i++)
            {
                itemSource.Add("Item " + i);
            }

            var flowItems = new FlowItemsControl3D();
            flowItems.SelectedIndex = 0;

            flowItems.ItemsSource = itemSource;

            TestPanel.Children.Add(flowItems);
            TestPanel.Children.Add(new StackPanel
            {
                VerticalAlignment = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Center,
                Children = { new TextBlock { Text = "Is this no cyclic mode coverflow right ?" }, yesBtn, noBtn }
            });
            EnqueueConditional(() => hasFinished);
            EnqueueCallback(() => Assert.IsTrue(isOk));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestCyclic5Items()
        {
            Button yesBtn = new Button { Content = "Yes" };
            Button noBtn = new Button { Content = "No" };

            bool isOk = false;
            bool hasFinished = false;
            yesBtn.Click += delegate
            {
                isOk = true;
                hasFinished = true;
            };


            noBtn.Click += delegate
            {
                hasFinished = true;
            };

            var itemSource = new List<string>();
            for (int i = 0; i < 5; i++)
            {
                itemSource.Add("Item " + i);
            }

            var flowItems = new FlowItemsControl3D();
            flowItems.SelectedIndex = 0;

            flowItems.ItemsSource = itemSource;

            TestPanel.Children.Add(flowItems);
            TestPanel.Children.Add(new StackPanel
            {
                VerticalAlignment = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Center,
                Children = { new TextBlock { Text = "Is this no cyclic mode coverflow right ?" }, yesBtn, noBtn }
            });
            EnqueueConditional(() => hasFinished);
            EnqueueCallback(() => Assert.IsTrue(isOk));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestNoCyclic20Items()
        {
            Button yesBtn = new Button{Content = "Yes"};
            Button noBtn = new Button{Content = "No"};

            bool isOk = false;
            bool hasFinished = false;
            yesBtn.Click += delegate
                                {
                                    isOk = true;
                                    hasFinished = true;
                                };


            noBtn.Click += delegate
            {
                hasFinished = true;
            };

            var itemSource = new List<string>();
            for(int i=0;i<20;i++)
            {
                itemSource.Add("Item "+i);
            }

            var flowItems = new FlowItemsControl3D();
            flowItems.SelectedIndex = 0;
            flowItems.CyclicMode = false;
           
            flowItems.ItemsSource = itemSource;

            TestPanel.Children.Add(flowItems);
            TestPanel.Children.Add(new StackPanel{VerticalAlignment = VerticalAlignment.Bottom, HorizontalAlignment = HorizontalAlignment.Center,
            Children = {new TextBlock{Text = "Is this no cyclic mode coverflow right ?"}, yesBtn, noBtn}});
            EnqueueConditional(()=>hasFinished);
            EnqueueCallback(()=>Assert.IsTrue(isOk));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestNoCyclic11Items()
        {
            Button yesBtn = new Button { Content = "Yes" };
            Button noBtn = new Button { Content = "No" };

            bool isOk = false;
            bool hasFinished = false;
            yesBtn.Click += delegate
            {
                isOk = true;
                hasFinished = true;
            };


            noBtn.Click += delegate
            {
                hasFinished = true;
            };

            var itemSource = new List<string>();
            for (int i = 0; i < 11; i++)
            {
                itemSource.Add("Item " + i);
            }

            var flowItems = new FlowItemsControl3D();
            flowItems.SelectedIndex = 0;
            flowItems.CyclicMode = false;

            flowItems.ItemsSource = itemSource;

            TestPanel.Children.Add(flowItems);
            TestPanel.Children.Add(new StackPanel
            {
                VerticalAlignment = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Center,
                Children = { new TextBlock { Text = "Is this no cyclic mode coverflow right ?" }, yesBtn, noBtn }
            });
            EnqueueConditional(() => hasFinished);
            EnqueueCallback(() => Assert.IsTrue(isOk));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestNoCyclic5Items()
        {
            Button yesBtn = new Button { Content = "Yes" };
            Button noBtn = new Button { Content = "No" };

            bool isOk = false;
            bool hasFinished = false;
            yesBtn.Click += delegate
            {
                isOk = true;
                hasFinished = true;
            };


            noBtn.Click += delegate
            {
                hasFinished = true;
            };

            var itemSource = new List<string>();
            for (int i = 0; i < 5; i++)
            {
                itemSource.Add("Item " + i);
            }

            var flowItems = new FlowItemsControl3D();
            flowItems.SelectedIndex = 0;
            flowItems.CyclicMode = false;

            flowItems.ItemsSource = itemSource;

            TestPanel.Children.Add(flowItems);
            TestPanel.Children.Add(new StackPanel
            {
                VerticalAlignment = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Center,
                Children = { new TextBlock { Text = "Is this no cyclic mode coverflow right ?" }, yesBtn, noBtn }
            });
            EnqueueConditional(() => hasFinished);
            EnqueueCallback(() => Assert.IsTrue(isOk));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void TestItemsSourceSetDynamically()
        {
            Button yesBtn = new Button { Content = "Yes" };
            Button noBtn = new Button { Content = "No" };

            bool isOk = false;
            bool hasFinished = false;
            yesBtn.Click += delegate
            {
                isOk = true;
                hasFinished = true;
            };


            noBtn.Click += delegate
            {
                hasFinished = true;
            };

            var itemSource = new List<string>();
            for (int i = 0; i < 5; i++)
            {
                itemSource.Add("Item " + i);
            }

            var flowItems = new FlowItemsControl3D();
            flowItems.SelectedIndex = 0;
            flowItems.CyclicMode = false;


            TestPanel.Children.Add(flowItems);
            TestPanel.Children.Add(new StackPanel
            {
                VerticalAlignment = VerticalAlignment.Bottom,
                HorizontalAlignment = HorizontalAlignment.Center,
                Children = { new TextBlock { Text = "Does this coverflow look correct ?" }, yesBtn, noBtn }
            });
            EnqueueDelay(1000);
            EnqueueCallback(() => flowItems.ItemsSource = itemSource);
            EnqueueConditional(() => hasFinished);
            EnqueueCallback(() => Assert.IsTrue(isOk));
            EnqueueTestComplete();
        }

    }

    
}